'use strict';

const Controller = require('egg').Controller;

// 默认头像，放在 user.js 的最外部，避免重复声明
const defaultAvatar = 'https://tse4-mm.cn.bing.net/th/id/OIP-C.9cLKJga4E0x-YevwT3OB4wAAAA?rs=1&pid=ImgDetMain';

class HomeController extends Controller {
  // 注册
  async register() {
    const {
      ctx,
    } = this;
    const {
      username,
      password,
    } = ctx.request.body;
    // 判空操作
    if (!username || !password) {
      ctx.body = {
        code: 400,
        message: '用户名或密码不能为空',
      };
      return;
    }
    // 验证数据库内是否已经有该账户名
    const userInfo = await ctx.service.user.getUserByName(username);

    // 判断是否已经存在
    if (userInfo && userInfo.id) {
      ctx.body = {
        code: 400,
        message: '该用户名已存在',
        data: null,
      };
      return;
    }
    // 调用 service 方法，将数据存入数据库
    const result = await ctx.service.user.register({
      username,
      password,
      signature: '默认签名',
      avatar: defaultAvatar,
    });

    if (result) {
      ctx.body = {
        code: 200,
        message: '注册成功',
        data: null,
      };
    } else {
      ctx.body = {
        code: 500,
        message: '注册失败',
        data: null,
      };
    }
  }
  // 登录
  async login() {
    const { ctx, app } = this;
    const { username, password } = ctx.request.body;
    // 根据用户名，在数据库查找相对应的id操作
    const userInfo = await ctx.service.user.getUserByName(username);
    // 未找到
    if (!userInfo || !userInfo.id) {
      ctx.body = {
        code: 400,
        message: '用户名不存在',
        data: null,
      };
      return;
    }
    // 找到用户，并且判断输入密码与数据库中用户密码
    if (userInfo.password !== password && userInfo) {
      ctx.body = {
        code: 400,
        message: '密码错误',
        data: null,
      };
      return;
    }

    // 生成 token 加密
    // app.jwt.sign 方法接受两个参数，第一个为对象，对象内是需要加密的内容；第二个是加密字符串，
    const token = app.jwt.sign({
      id: userInfo.id,
      username: userInfo.username,
      exp: Math.floor(Date.now() / 1000) + (60 * 60 * 24 * 7), // 7天过期
    }, app.config.jwt.secret);

    ctx.body = {
      code: 200,
      message: '登录成功',
      data: {
        token,
      },
    };
  }
  // 测试接口
  async test() {
    const { ctx, app } = this;
    // 通过token解析，拿到user_id
    // 请求头获取authorization属性，值为token
    const token = ctx.request.header.authorization;
    // 通过app.jwt.verify + 加密字符串 解析出 token 的值
    const decode = app.jwt.verify(token, app.config.jwt.secret);
    // 响应接口
    ctx.body = {
      code: 200,
      msg: '获取成功',
      data: {
        ...decode,
      },
    };
  }
  // 获取用户信息
  async getUserInfo() {
    const { ctx, app } = this;
    // 通过 app.jwt.verify 方法，解析出 token 内的用户信息
    const token = ctx.request.header.authorization;
    const decode = app.jwt.verify(token, app.config.jwt.secret);
    //  通过 getUserByName 方法，以用户名 decode.username 为参数，从数据库获取到该用户名下的相关信息
    const userInfo = await ctx.service.user.getUserByName(decode.username);
    // userInfo 中应有密码信息，所有指定下面四项返回给客户端
    if (userInfo) {
      ctx.body = {
        code: 200,
        message: '请求成功',
        data: {
          username: userInfo.username,
          signature: userInfo.signature,
          avatar: userInfo.avatar || defaultAvatar,
        },
      };
    }
  }
  // 修改用户信息
  async editUserInfo() {
    const { ctx, app } = this;
    //  通过post请求，在请求体中获取签名字段 signature
    const { signature = '', avatar = '' } = ctx.request.body;

    try {
      let user_id;
      const token = ctx.request.header.authorization;
      // 解密 token 中的用户名称
      const decode = app.jwt.verify(token, app.config.jwt.secret);
      if (!decode) return;
      // eslint-disable-next-line prefer-const
      user_id = decode.id;
      // 通过 username 查找 userInfo 完整信息
      const userInfo = await ctx.service.user.getUserByName(decode.username);
      // 通过 service 方法 editUserInfo 修改 signature 信息。
      const result = await ctx.service.user.editUserInfo({
        ...userInfo,
        signature,
        avatar,
      });

      ctx.body = {
        code: 200,
        msg: '请求成功',
        data: {
          id: user_id,
          signature,
          username: userInfo.username,
          avatar,
        },
      };
    } catch (error) {
      console.log(error);
    }
  }
}

module.exports = HomeController;
